package com.example.basic.web.service.newly.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.basic.base.impl.BaseEntityServiceImpl;
import com.example.basic.core.result.Result;
import com.example.basic.core.result.ResultGenerator;
import com.example.basic.exception.ServiceException;
import com.example.basic.utils.HttpUtils;
import com.example.basic.utils.IdUtils;
import com.example.basic.web.mapper.device.DeviceMapper;
import com.example.basic.web.mapper.newly.SysBacklogMapper;
import com.example.basic.web.mapper.newly.SysExceptionalRecoveryMapper;
import com.example.basic.web.mapper.newly.SysFlowTaskMapper;
import com.example.basic.web.mapper.newly.SysPdaFlowMapper;
import com.example.basic.web.model.device.Device;
import com.example.basic.web.model.newly.SysBacklog;
import com.example.basic.web.model.newly.SysExceptionalRecovery;
import com.example.basic.web.model.newly.SysFlowTask;
import com.example.basic.web.model.newly.SysPdaFlow;
import com.example.basic.web.request.SysExceptionalRecoveryDto;
import com.example.basic.web.service.newly.ISysExceptionalRecoveryService;
import com.example.basic.web.webSocket.WebSocketServerUtil;
import io.swagger.models.auth.In;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.Date;
import java.util.List;

import static com.example.basic.web.service.newly.impl.SysPdaFlowServiceImpl.*;

@Service
public class SysExceptionalRecoveryImpl extends BaseEntityServiceImpl<SysExceptionalRecoveryMapper, SysExceptionalRecovery> implements ISysExceptionalRecoveryService {

    @Resource
    private SysExceptionalRecoveryMapper sysExceptionalRecoveryMapper;

    @Resource
    private SysFlowTaskMapper sysFlowTaskMapper;

    @Resource
    private SysPdaFlowMapper sysPdaFlowMapper;

    @Resource
    private DeviceMapper deviceMapper;

    @Resource
    private SysBacklogMapper sysBacklogMapper;

    /**
     * 1）转运任务中，起点接驳设备故障
     * 第一步先把任务取消了
     *
     * @return
     */
    @Override
    public Result<Boolean> firstCancel(SysExceptionalRecoveryDto zyExceptionalRecoveryDto) {
        SysPdaFlow sysPdaFlow = sysPdaFlowMapper.selectById(zyExceptionalRecoveryDto.getFlowId());
        //查询是否有正在执行且未取货的任务
        LambdaQueryWrapper<SysFlowTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysFlowTask::getFlowId, zyExceptionalRecoveryDto.getFlowId());
        queryWrapper.eq(SysFlowTask::getEndStatus, 0);
        List<SysFlowTask> sysFlowTasks = sysFlowTaskMapper.selectList(queryWrapper);
        if (sysFlowTasks.isEmpty()) {
            throw new ServiceException("没有正在执行的任务");
        }
        //删除当前任务,直接删除即可
        for (SysFlowTask sysFlowTask : sysFlowTasks) {
            sysFlowTaskMapper.deleteById(sysFlowTask.getId());
        }

        //流程回滚
        flowRollback(sysPdaFlow);

        return ResultGenerator.genSuccessResult(true);
    }

    /**
     * 发送变更位置
     * @param zyExceptionalRecoveryDto
     * @return
     */
    @Override
    public Result<Boolean> changePosition(SysExceptionalRecoveryDto zyExceptionalRecoveryDto) {
        //查询当前任务
        SysPdaFlow sysPdaFlow = sysPdaFlowMapper.selectById(zyExceptionalRecoveryDto.getFlowId());

        String taskRecordId = IdUtils.fastUUID();
        SysFlowTask sysFlowTask = new SysFlowTask();
        sysFlowTask.setId(taskRecordId);
        sysFlowTask.setFlowId(zyExceptionalRecoveryDto.getFlowId());
        sysFlowTask.setStartPositionId(sysPdaFlow.getPositionId());
        sysFlowTask.setEndPositionId(zyExceptionalRecoveryDto.getTargetPositionId());
        sysFlowTask.setStartStatus(0);
        sysFlowTask.setEndStatus(0);
        sysFlowTask.setCreateAt(new Date());
        sysFlowTask.setUpdateAt(new Date());
        sysFlowTask.setNowStage(16);
        sysFlowTaskMapper.insert(sysFlowTask);

        Device endDevice = deviceMapper.selectById(zyExceptionalRecoveryDto.getTargetPositionId());
        Device device = deviceMapper.selectById(sysPdaFlow.getPositionId());


        try {
            HttpUtils.sendPost(null,device.getDevicePoint(),endDevice.getDevicePoint(),taskRecordId);
        } catch (IOException e) {
            throw new ServiceException("调度失败请联系管理员");

        }


        SysExceptionalRecovery sysExceptionalRecovery = new SysExceptionalRecovery();
        sysExceptionalRecovery.setFlowId(zyExceptionalRecoveryDto.getFlowId());
        sysExceptionalRecovery.setType(zyExceptionalRecoveryDto.getType());
        sysExceptionalRecovery.setTaskId(taskRecordId);
        sysExceptionalRecovery.setId(IdUtils.fastUUID());

        //提前判断发送成功后需要给谁发消息
        String stageAdmin = getStageAdmin(sysPdaFlow.getNowStage());
        if (stageAdmin != null) {
            sysExceptionalRecovery.setTargetUserId(stageAdmin);
        }

        sysExceptionalRecovery.setCreateAt(new Date());
        sysExceptionalRecovery.setUpdateAt(new Date());
        sysExceptionalRecoveryMapper.insert(sysExceptionalRecovery);

        return ResultGenerator.genSuccessResult(true);

    }

    /**
     * 第二个异常 强制成功
     * @param zyExceptionalRecoveryDto
     * @return
     */
    @Override
    public Result<Boolean> secondSuccess(SysExceptionalRecoveryDto zyExceptionalRecoveryDto) {
        SysPdaFlow sysPdaFlow = sysPdaFlowMapper.selectById(zyExceptionalRecoveryDto.getFlowId());
        //查询是否有正在执行且未取货的任务
        LambdaQueryWrapper<SysFlowTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysFlowTask::getFlowId, zyExceptionalRecoveryDto.getFlowId());
        queryWrapper.eq(SysFlowTask::getEndStatus, 0);
        queryWrapper.orderByDesc(SysFlowTask::getCreateAt);
        List<SysFlowTask> sysFlowTasks = sysFlowTaskMapper.selectList(queryWrapper);
        if (sysFlowTasks.isEmpty()) {
            throw new ServiceException("没有正在执行的任务");
        }
        SysFlowTask sysFlowTask = sysFlowTasks.get(0);
        sysFlowTask.setEndStatus(1);
        sysFlowTask.setStartStatus(1);
        sysFlowTask.setUpdateAt(new Date());
        sysFlowTaskMapper.updateById(sysFlowTask);

        sysPdaFlow.setPositionId(sysFlowTask.getEndPositionId());
        sysPdaFlow.setUpdateAt(new Date());
        sysPdaFlowMapper.updateById(sysPdaFlow);
        return ResultGenerator.genSuccessResult(true);
    }

    /**
     * 异常三 异常四 处理方式一样
     * 先回滚 回滚完成后 重新给当前阶段负责人发消息
     * @param zyExceptionalRecoveryDto
     * @return
     */
    @Override
    public Result<Boolean> rollBack(SysExceptionalRecoveryDto zyExceptionalRecoveryDto) {
        SysPdaFlow sysPdaFlow = sysPdaFlowMapper.selectById(zyExceptionalRecoveryDto.getFlowId());
        //查询是否有正在执行且未取货的任务
        LambdaQueryWrapper<SysFlowTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysFlowTask::getFlowId, zyExceptionalRecoveryDto.getFlowId());
        queryWrapper.eq(SysFlowTask::getEndStatus, 0);
        List<SysFlowTask> sysFlowTasks = sysFlowTaskMapper.selectList(queryWrapper);
        if (sysFlowTasks.isEmpty()) {
            return ResultGenerator.genSuccessResult(true);
        }
        //删除当前任务,直接删除即可
        for (SysFlowTask sysFlowTask : sysFlowTasks) {
            sysFlowTaskMapper.deleteById(sysFlowTask.getId());
        }

        System.out.println(sysPdaFlow.getNowStage());
        //流程回滚
        flowRollback(sysPdaFlow);
        //重新给当前阶段负责人发消息
        System.out.println(sysPdaFlow.getNowStage());
        String stageAdmin = getStageAdmin(sysPdaFlow.getNowStage());

        SysBacklog sysBacklog = new SysBacklog();
        sysBacklog.setFlowId(zyExceptionalRecoveryDto.getFlowId());
        sysBacklog.setSysUserId(stageAdmin);
        sysBacklog.setCreateAt(new Date());
        sysBacklog.setUpdateAt(new Date());
        sysBacklog.setStatus(FLOW_STATUS_NO);
        sysBacklog.setId(IdUtils.fastUUID());
        sysBacklogMapper.insert(sysBacklog);
        WebSocketServerUtil.sendInfo("来新任务了", stageAdmin);

        return ResultGenerator.genSuccessResult(true);
    }

    /**
     * 异常五
     * 强制完成当前该流程 然后给终点负责人发代办
     * @param zyExceptionalRecoveryDto
     * @return
     */
    @Override
    public Result<Boolean> fifthComplete(SysExceptionalRecoveryDto zyExceptionalRecoveryDto) {
        SysPdaFlow sysPdaFlow = sysPdaFlowMapper.selectById(zyExceptionalRecoveryDto.getFlowId());
        //查询是否有正在执行且未取货的任务
        LambdaQueryWrapper<SysFlowTask> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysFlowTask::getFlowId, zyExceptionalRecoveryDto.getFlowId());
        queryWrapper.eq(SysFlowTask::getEndStatus, 0);
        List<SysFlowTask> sysFlowTasks = sysFlowTaskMapper.selectList(queryWrapper);
        if (sysFlowTasks.isEmpty()) {
            throw new ServiceException("没有正在执行的任务");
        }
        SysFlowTask sysFlowTask = sysFlowTasks.get(0);
        sysFlowTask.setEndStatus(1);
        sysFlowTask.setStartStatus(1);
        sysFlowTask.setUpdateAt(new Date());
        sysFlowTaskMapper.updateById(sysFlowTask);

        sysPdaFlow.setPositionId(sysFlowTask.getEndPositionId());
        sysPdaFlow.setUpdateAt(new Date());
        sysPdaFlowMapper.updateById(sysPdaFlow);

        String stageAdmin = getStageAdmin(sysPdaFlow.getNowStage());

        SysBacklog sysBacklog = new SysBacklog();
        sysBacklog.setFlowId(zyExceptionalRecoveryDto.getFlowId());
        sysBacklog.setSysUserId(stageAdmin);
        sysBacklog.setCreateAt(new Date());
        sysBacklog.setUpdateAt(new Date());
        sysBacklog.setStatus(FLOW_STATUS_NO);
        sysBacklog.setId(IdUtils.fastUUID());
        sysBacklogMapper.insert(sysBacklog);
        WebSocketServerUtil.sendInfo("来新任务了", stageAdmin);

        return ResultGenerator.genSuccessResult(true);
    }

    /**
     * 流程回滚
     *
     * @param sysPdaFlow
     */
    public void flowRollback(SysPdaFlow sysPdaFlow) {
        //1暂存区 2消毒 3 spa 4冰柜 5化妆 6二次信息确认 7瞻仰 8火化
        Integer nowStage = sysPdaFlow.getNowStage();

        //回滚到上一个阶段
        switch (nowStage) {
            case 1:
                //
                break;
            case 2:
                //正在发往消毒,流程回滚到暂存区
                sysPdaFlow.setNowStage(1);
                sysPdaFlow.setUpdateAt(new Date());
                sysPdaFlow.setDisinfectStatus(FLOW_STATUS_NO);
                sysPdaFlow.setMsgFirstAffirm(FLOW_STATUS_WAIT_SURE);

                break;
            case 3:
                //发往spa spa上个阶段是消毒，流程回滚到消毒
                sysPdaFlow.setNowStage(2);
                sysPdaFlow.setUpdateAt(new Date());
                sysPdaFlow.setSpaStatus(FLOW_STATUS_NO);
                sysPdaFlow.setDisinfectStatus(FLOW_STATUS_WAIT_SURE);
                break;
            case 5:
                //发往化妆 判断有没有spa,需要spa,流程回滚到spa,没有的话回滚到消毒
                sysPdaFlow.setMakeStatus(FLOW_STATUS_NO);
                if (sysPdaFlow.getIsSpa() == FLOW_STATUS_YES) {
                    sysPdaFlow.setNowStage(3);
                    sysPdaFlow.setUpdateAt(new Date());
                    sysPdaFlow.setSpaStatus(FLOW_STATUS_WAIT_SURE);
                } else {
                    sysPdaFlow.setNowStage(2);
                    sysPdaFlow.setUpdateAt(new Date());
                    sysPdaFlow.setDisinfectStatus(FLOW_STATUS_WAIT_SURE);
                }
                break;

            case 6:
                //发往二次确认 先判断是否有化妆,有的话回滚到化妆,没有的话判断是否有spa,有的话回滚到spa,没有的话回滚到消毒
                sysPdaFlow.setMsgSecondAffirm(FLOW_STATUS_NO);
                if (sysPdaFlow.getIsMake() == FLOW_STATUS_YES) {
                    sysPdaFlow.setNowStage(5);
                    sysPdaFlow.setUpdateAt(new Date());
                    sysPdaFlow.setMakeStatus(FLOW_STATUS_WAIT_SURE);
                } else {
                    if (sysPdaFlow.getIsSpa() == FLOW_STATUS_YES) {
                        sysPdaFlow.setNowStage(3);
                        sysPdaFlow.setUpdateAt(new Date());
                        sysPdaFlow.setSpaStatus(FLOW_STATUS_WAIT_SURE);
                    } else {
                        sysPdaFlow.setNowStage(2);
                        sysPdaFlow.setUpdateAt(new Date());
                        sysPdaFlow.setDisinfectStatus(FLOW_STATUS_WAIT_SURE);
                    }
                }
                break;
            case 7:
                //发往瞻仰 返回到二次确认
                sysPdaFlow.setAdmireStatus(FLOW_STATUS_NO);
                sysPdaFlow.setNowStage(6);
                sysPdaFlow.setUpdateAt(new Date());
                sysPdaFlow.setMsgSecondAffirm(FLOW_STATUS_WAIT_SURE);
                break;
            case 8:
                //发往火化 判断有没有瞻仰
                sysPdaFlow.setFireStatus(FLOW_STATUS_NO);

                if (sysPdaFlow.getIsAdmire() == FLOW_STATUS_YES) {
                    sysPdaFlow.setNowStage(7);
                    sysPdaFlow.setUpdateAt(new Date());
                    sysPdaFlow.setAdmireStatus(FLOW_STATUS_WAIT_SURE);
                } else {
                    sysPdaFlow.setNowStage(6);
                    sysPdaFlow.setUpdateAt(new Date());
                    sysPdaFlow.setMsgSecondAffirm(FLOW_STATUS_WAIT_SURE);
                }
                break;
            case 9:
                // 火化完成返回 返回火化
                sysPdaFlow.setNowStage(8);
                sysPdaFlow.setUpdateAt(new Date());
                sysPdaFlow.setFireStatus(FLOW_STATUS_WAIT_SURE);
                break;
            default:
                break;
        }
        sysPdaFlowMapper.updateById(sysPdaFlow);
    }

    public String getStageAdmin(Integer stage){
        String userId = "";
        switch (stage) {
            case 1:
                //暂存区负责人
                userId = "308007ce-f0ca-4c11-8057-5703699c6e7e";
                break;
            case 2:
                //消毒区负责人
                userId = "be1260df-639d-4599-a121-ec928f793c45";
                break;
            case 3:
                //spa负责人
                userId = "02c5ffff-15a0-4291-8581-00a2d08f232a";
                return "消毒";
            case 4:
                //化妆
                userId="2a503a42-17a8-4306-844f-8682475ebb7b";
                break;
            case 6:
                //二次确认
                userId= "0c3bd3cf-02c7-44fd-8ef6-4bca11a92d22";
                break;
            case 7:
                //瞻仰
                userId= "f4668902-09c2-4e8b-b34b-2c09aa2a22d4";
                break;
            case 8:
                //火化
                userId= "e2c66174-f836-449e-b02c-fbdda899fccf";
                break;
        }
        return userId;
    }
}
